Assembly Workbench/pl

Ikonka FreCAD dla środowiska pracy Złożenie

Wprowadzenie

dostępne w wersji 1.0

Środowisko pracy Złożenie to nowe wbudowane środowisko pracy FreeCAD do modelowania złożeń. Korzysta z otwartoźródłowego solvera Ondsel.

Narzędzia

Złożenie

Połączenia

  • Utwórz połączenie pasowe: tworzy połączenie przekładni pasowej, które wiąże obrót dwóch części z dwoma różnymi połączeniami typu Obrotowe.

Ustawienia

Przykład - korba i suwak

Ten przykład jest tymczasowy i może zostać usunięty gdy pojawią się odpowiednie opisy/przykłady.

Złożenie - korba i suwak

Złożenie, które ma zostać utworzone, składa się z czterech części: podstawy, suwaka, korby i korbowodu. Są one połączone czterema przegubami.

Złożone części: Podstawa (bursztynowy), Suwak (jasnoniebieski), Korba (czerwony), Korbowód (zielony)

Przygotowanie części

W tym przykładzie wszystkie części i zespół są tworzone w jednym dokumencie.

Geometrie cylindryczne obiektów są równoległe lub prostopadłe, pozostałe kształty nie są istotne dla tego przykładu, chyba że występują kolizje. Mając to na uwadze, możesz zamodelować własne obiekty lub utworzyć je przy pomocy poniższego kodu Pythona. Ten kod utworzy nowy dokument z czterema obiektami (prostszymi niż na rysunkach). Po prostu skopiuj i wklej następujące linie do konsoli Pythona:

import FreeCAD as App
import FreeCADGui as Gui
import Part

doc = App.newDocument()

box1 = Part.makeBox(140, 40, 7, App.Vector(0, -20, 0))
cyl1 = Part.makeCylinder(4, 8, App.Vector(120, 0, 7))
box2 = Part.makeBox(20, 12, 10, App.Vector(5, -6, 7))
cyl2 = Part.makeCylinder(6, 20, App.Vector(25, 0, 17), App.Vector(-1, 0, 0))
cyl3 = Part.makeCylinder(4, 20, App.Vector(25, 0, 17), App.Vector(-1, 0, 0))
shape = box1.fuse([cyl1, box2, cyl2]).removeSplitter().cut(cyl3)
base = doc.addObject("Part::Feature", "Base")
base.Shape = shape

box1 = Part.makeBox(4, 12, 12, App.Vector(-12, -6, 0))
box2 = Part.makeBox(14, 12, 4, App.Vector(-8, -6, 0))
cyl1 = Part.makeCylinder(4, 8, App.Vector(0, 0, 4))
cyl2 = Part.makeCylinder(4, 88, App.Vector(-12, 0, 6),App.Vector(-1, 0, 0))
shape = box1.fuse([box2, cyl1, cyl2]).removeSplitter()
slider_rod = doc.addObject("Part::Feature", "SliderRod")
slider_rod.Shape = shape
slider_rod.Placement.Base = App.Vector(100, -40, 0)

cyl1 = Part.makeCylinder(7.5, 4)
box1 = Part.makeBox(15, 30, 4, App.Vector(-7.5, 0, 0))
cyl2 = Part.makeCylinder(7.5, 4, App.Vector(0, 30, 0))
cyl3 = Part.makeCylinder(4, 6, App.Vector(0, 30, 4))
cyl4 = Part.makeCylinder(4, 4)
shape = cyl1.fuse([box1, cyl2]).removeSplitter().fuse(cyl3).cut(cyl4)
crank = doc.addObject("Part::Feature", "Crank")
crank.Shape = shape
crank.Placement.Base = App.Vector(125, -70, 0)

cyl1 = Part.makeCylinder(6, 4)
box1 = Part.makeBox(50, 12, 4, App.Vector(0, -6, 0))
cyl2 = Part.makeCylinder(6, 4, App.Vector(50, 0, 0))
cyl3 = Part.makeCylinder(4, 4)
cyl4 = Part.makeCylinder(4, 4, App.Vector(50, 0, 0))
shape = cyl1.fuse([box1, cyl2]).removeSplitter().cut(cyl3.fuse(cyl4))
connecting_rod = doc.addObject("Part::Feature", "ConnectingRod")
connecting_rod.Shape = shape
connecting_rod.Placement.Base = App.Vector(25, -70, 0)

mat = base.ViewObject.ShapeAppearance[0]
mat.DiffuseColor = (0.80, 0.60, 0.15, 0.0)
base.ViewObject.ShapeAppearance = (mat,)

mat = slider_rod.ViewObject.ShapeAppearance[0]
mat.DiffuseColor = (0.55, 0.70, 0.70, 0.0)
slider_rod.ViewObject.ShapeAppearance = (mat,)

mat = crank.ViewObject.ShapeAppearance[0]
mat.DiffuseColor = (0.70, 0.30, 0.20, 0.0)
crank.ViewObject.ShapeAppearance = (mat,)

mat = connecting_rod.ViewObject.ShapeAppearance[0]
mat.DiffuseColor = (0.55, 0.70, 0.0, 0.0)
connecting_rod.ViewObject.ShapeAppearance = (mat,)

doc.recompute()
view = Gui.ActiveDocument.ActiveView
view.viewIsometric()
view.fitAll()

Dodawanie złożenia

Przy pomocy polecenia Utwórz złożenie dodaj do dokumentu złożenie.

Widok drzewa części i złożenia.

Przenieś części do złożenia

W Widoku drzewa przeciągnij i upuść części na obiekt Złożenia. Teraz mogą być one obsługiwane przez solver złożeń.

Części są teraz w kontenerze złożeń.

Kotwienie części

Aby utrzymać złożenie w pożądanej pozycji, część bazowa powinna zostać zablokowana lub zakotwiona, jak to się tutaj nazywa. Wybierz bazę w widoku drzewa lub w widoku 3D i użyj polecenia Włącz / wyłącz zakotwienie. Spowoduje to ustalenie pozycji Bazy w odniesieniu do lokalnego układu współrzędnych (LCS) kontenera złożenia. Obiekt GroundedJoint zostanie dodany do kontenera Joints.

Rozwiń kontener Połączeń, aby znaleźć obiekt Zakotwienia połaczeń.

Alternatywa: Wstaw łącze

Zamiast dwóch kroków opisanych wyżej, można również użyć polecenia Wstaw łącze aby umieścić obiekty w złożeniu. Pierwszy obiekt automatycznie zostaje zakotwiony. Musisz więc zacząć od obiektu podstawy. To polecenie tworzy łącza i oryginalne obiekty pozostają poza złożeniem. Aby uniknąć wątpliwości, zalecane jest wyłączanie ich widoczności.

Zastosuj połączenia

Połączenie łączy dokładnie dwa elementy różnych części. Można je opcjonalnie wybrać przed wywołaniem żądanego polecenia połączenia (dowolna liczba wybranych elementów innych niż dwa powoduje pusty wybór). Elementy definiują położenie i orientację LCS reprezentowanego przez wypełniony okrąg na lokalnej płaszczyźnie XY i trzy linie wzdłuż lokalnych osi X (czerwony), Y (zielony) i Z (niebieski).

  • Połączenie obrotowe między podstawą a korbą.

Zaznaczone elementy + Utwórz połączenie obrotowe → przestawiona korba.

Przesuń Korbę używając lewego przycisku myszy. Tylko obrót wokół osi powinien być możliwy.

  • Połączenie przesuwne między podstawą a suwakiem.

Selected elements + Utwórz połączenie przesuwne → przestawiony suwak

Przesuń Suwak używając lewego przycisku myszy. Tylko przemieszczenie wzdłuż jego osi powinno być możliwe.

  • Połączenie obrotowe między korbą a korbowodem.

Zaznaczone elementy + Utwórz połączenie obrotowe → przestawiony korbowód

Przesuń Korbowód używając lewego przycisku myszy. Tylko obrót wokół osi powinien być możliwy.

Jeśli jest kilka połączeń w linii, musimy pomóc solverowi w znalezieniu sensownego rozwiązania. Jeśli to konieczne, kliknij i przeciągnij części do łatwiejszej do obliczenia pozycji.

  • Połączenie cylindryczne między korbowodem a suwakiem.

Zaznaczone elementy + Utwórz połączenie cylindryczne → zakończone złożenie

W gotowym złożeniu użyj kursora myszki, aby przeciągnąć części zgodnie z użytymi połączeniami.

Uwaga

Sworzeń pręta suwaka jest nadmiarowo zorientowany. Jego oś jest równoległa do sworznia podstawy poprzez łańcuch kinematyczny z podstawy przez korbę i korbowód, t.j. jego lokalna oś Z nie może się obracać wokół żadnej osi X lub Y. Połączenie przesuwne również zapobiega obrotowi jego osi Z wokół dwóch lokalnych osi a więc skutkuje dwoma nadmiarowo związanymi stopniami swobody. Połączenie cylindryczne zamiast przesuwnego zablokowałoby tylko jeden obrót skutkując pojedynczym nadmiernie związanym stopniem swobody.

Napęd korby

Aby kontrolować układ złożenia za pomocą kąta między podstawą a korbą, musimy zmienić połączenie obrotowe na stałe. Aby to zrobić, kliknij dwukrotnie obiekt Obrotowy w widoku drzewa. W oknie dialogowym zmień Obrotowy na Stały i zmień wartość obrotu zgodnie z potrzebą (ruch powinien podążać za ruchem kółka myszki).

Zauważ, że zmiana typu połączenia zmieni jego etykietę, ale nie nazwę. W tym przypadku etykiety zostaje zmieniona na "Stałe".

Aby dokonać animacji złożenia, możemy zmienić obrót (Offset1.Angle) połączenia stałego używając kodu Pythona. Po prostu skopiuj i wklej następujące linie do konsoli Pythona:

import math
import FreeCAD as App
import FreeCADGui as Gui

actuator = App.ActiveDocument.getObjectsByLabel("Fixed")[0]

for angle in range(0, 361, 10):
    # A full rotation of the Crank in steps of 10°
    actuator.Offset1.Rotation.Angle = math.radians(angle)
    App.ActiveDocument.recompute()
    Gui.updateGui()

Koniec zakresu musi być większy niż 360, aby uwzględnić ten kąt jako prawidłowy wynik.

Przykład - przegub Cardana

Ten przykład jest tymczasowy i może zostać usunięty gdy pojawią się odpowiednie opisy/przykłady.

Złożenie przegubu Cardana

W tym przykładzie tworzony jest przegub Cardana.

Złożenie składa się z trzech części bryłowych: dwóch identycznych widelców i krzyżowego łącznika. Potrzebne są też dwa dodatkowe elementy niebryłowe, oś 1 i oś 2 reprezentujące osie pod kątem. Osie i części bryłowe są połączone kilkoma połączeniami.

Przygotowanie części

W tym przykładzie wszystkie części i złożenie są tworzone w jednym dokumencie.

Poniższy kod Pythona utworzy nowy dokument z czterema obiektami (tylko 1 widelec). Po prostu skopiuj i wklej następujące linie do konsoli Pythona:

import math
import FreeCAD as App
import FreeCADGui as Gui
import Part

doc = App.newDocument()

axle1 = doc.addObject("Part::Line", "Axle1")
axle1.X2 = -80
axle1.Y2 = 0
axle1.Z2 = 0

axle2 = doc.addObject("Part::Line", "Axle2")
axle2.X2 = 80
axle2.Y2 = 0
axle2.Z2 = 0
axle2.Placement.Rotation.Angle = math.radians(20)

sph1 = Part.makeSphere(50, App.Vector(0, 0, 0), App.Vector(-1, 0, 0), 0, 90, 360)
box1 = Part.makeBox(50, 40, 80, App.Vector(-50, -20, -40))
cyl1 = Part.makeCylinder(20, 80, App.Vector(0, 0, -40))
cyl2 = Part.makeCylinder(20, 80, App.Vector(0, 0, 0), App.Vector(-1, 0, 0))
cyl3 = Part.makeCylinder(30, 60, App.Vector(0, -30, 0), App.Vector(0, 1, 0))
box2 = Part.makeBox(30, 60, 60, App.Vector(0, -30, -30))
cyl4 = Part.makeCylinder(15, 80, App.Vector(0, 0, -40))
cyl5 = Part.makeCylinder(15, 80, App.Vector(0, 0, 0), App.Vector(-1, 0, 0))
shape = sph1.common(box1).fuse([cyl1, cyl2]).cut(cyl3.fuse([box2, cyl4, cyl5]))
fork = doc.addObject("Part::Feature", "Fork")
fork.Shape = shape.removeSplitter()
fork.Placement.Base = App.Vector(0, 100, 0)

cyl1 = Part.makeCylinder(15, 80, App.Vector(0, 0, -40))
cyl2 = Part.makeCylinder(15, 80, App.Vector(0, -40, 0), App.Vector(0, 1, 0))
shape = cyl1.fuse([cyl2])
cross = doc.addObject("Part::Feature", "Cross")
cross.Shape = shape.removeSplitter()
cross.Placement.Base = App.Vector(70, 100, 0)

mat = fork.ViewObject.ShapeAppearance[0]
mat.DiffuseColor = (0.80, 0.60, 0.15, 0.0)
fork.ViewObject.ShapeAppearance = (mat,)

mat = cross.ViewObject.ShapeAppearance[0]
mat.DiffuseColor = (0.55, 0.70, 0.70, 0.0)
cross.ViewObject.ShapeAppearance = (mat,)

doc.recompute()
view = Gui.ActiveDocument.ActiveView
view.viewIsometric()
view.fitAll()

Zmień kąt osi

Kąt między osiami jest ustawiony na 20 stopni. Jeśli chcesz zmienić tą wartość, wybierz oś 2 i ustaw właściwość Umiejscowienie.Kąt. Ta właściwość musi być zmieniona przed przesunięciem osi 2 do złożenia.

Ostrzeżenie: części mogą ze sobą kolidować jeśli kąt jest zbyt duży.

Dodawanie złożenia

Dodaj złożenie do dokumentu korzystając z narzędzia Utwórz złożenie.

Przenieś osie do złożenia

W widoku drzewa przeciągnij i upuść osie do obiektu Złożenie.

Zakotwienie osi

Wybierz dwie osie w widoku drzewa i użyj narzędzia Włącz / wyłącz zakotwienie.

Przenieś części bryłowe do złożenia

Dla innych obiektów użyjemy narzędzia Wstaw komponent:

  1. Wywołaj to narzędzie.
  2. W oknie dialogowym, które zostanie otwarte kliknij raz na obiekcie łącznika krzyżowego i dwa razy na obiekcie widelca.
  3. Wciśnij przycisk OK.
  4. Schowaj obiekty poza złożeniem.
  5. Jeśli obiekty w złożeniu za bardzo na siebie nachodzą, możesz je przeciągnąć do nowej pozycji.

Zastosuj połączenia

  • Połączenie obrotowe między osią 1 i łącznikiem krzyżowym

Selected elements + Utweórz połączenie obrotowe + Odsunięcie +40mm lub -40mm → przestawiony widelec 1

Jeśli najpierw wywołujesz narzędzie a następnie wskazujesz elementy, możesz kliknąć w pobliżu prawidłowego punktu końcowego osi 1 aby uniknąć konieczności wprowadzania odsunięcia.

  • Połączenie cylindryczne między widelcem 1 i łącznikiem krzyżowym

Zaznaczone elementy + Utwórz połączenie cylindryczne → przestawiony łącznik krzyżowy

  • Połączenie cylindryczne między osią 1 i widelcem 2

Zaznaczone elementy + Utwórz połączenie cylindryczne → przestawiony widelec 2

Jeśli to konieczne, odwróć kierunek połączenia używając przycisku w panelu zadań.

  • Połączenie cylindryczne między łącznikiem krzyżowym i widelcem 2

Zaznaczone elementy + Utwórz połączenie cylindryczne → przestawiony łącznik krzyżowy i widelec 2

Sterowanie przegubem Cardana

Przegubem Cardana można sterować ruszając widelec 1 lewym przyciskiem myszy.

Jeśli chcesz sprawdzić sytuację dla osobnych kątów obrotu:

  1. Zmień połączenie cylindryczne między osią 1 i widelcem 1 na połączenie stałe.
  2. Wybierz właściwość Odsunięcie1.Kąt połączenia stałego i przesuń kółko myszy.
  3. Przegub Cardana może być ustawiony dla dowolnego kąta.

Przykład - imadło

Ten przykład jest tymczasowy i może zostać usunięty gdy pojawią się odpowiednie opisy/przykłady.

Złożenie imadła

W tym przykładzie modelowane jest imadło.

Złożenie składa się z trzech części bryłowych: stałej i ruchomej szczęki oraz śruby z dźwignią. Potrzebny jest też jeden dodatkowy element niebryłowy - korba. Między korbą a częściami bryłowymi jest kilka połączeń.

Połączenie śrubowe wiąże przesunięcie części z połączeniem przesuwnym z rotacją części z połączeniem obrotowym. Śruba powinna wykonywać ruch translacyjny i rotacyjny, więc musi być częścią z połączeniem cylindrycznym. W tym złożeniu śruba będzie sprzężona z ruchomą szczęką połączeniem dystansowym, z niebryłową korbą połączeniem równoległym a z nieruchomą szczęką połączeniem cylindrycznym.

Przygotowanie części

W tym przykładzie wszystkie części i złożenie są tworzone w jednym dokumencie.

Poniższy kod Pythona utworzy nowy dokument z czterema obiektami. Po prostu skopiuj i wklej następujące linie do konsoli Pythona:

import math
import FreeCAD as App
import FreeCADGui as Gui
import Part

doc = App.newDocument()

box1 = Part.makeBox(95, 40, 75, App.Vector(0, -20, -22))
cyl1 = Part.makeCylinder(35, 80, App.Vector(0, -40, 53), App.Vector(0, 1, 0), 90)
box2 = Part.makeBox(20, 80, 30, App.Vector(-20, -40, 58))
cyl2 = Part.makeCylinder(15, 80, App.Vector(-15, -40, 58), App.Vector(0, 1, 0), 90)
box3 = Part.makeBox(5, 80, 15, App.Vector(-20, -40, 58))
box4 = Part.makeBox(35, 24, 24, App.Vector(0, -12, -12))
box5 = Part.makeBox(60, 34, 69, App.Vector(35, -17, -19))
cyl3 = Part.makeCylinder(20, 55, App.Vector(-20, -40, 53), App.Vector(1, 0, 0))
cyl4 = Part.makeCylinder(20, 55, App.Vector(-20, 40, 53), App.Vector(1, 0, 0))
cyl5 = Part.makeCylinder(5, 35, App.Vector(0, 0, 38), App.Vector(1, 0, 0))
box6 = Part.makeBox(7, 88, 15, App.Vector(-22, -44, 75))
box7 = Part.makeBox(95, 90, 10, App.Vector(0, -45, -32))
shape = box1.fuse([cyl1, box2, box6, box7]).cut(cyl2.fuse([box3, cyl3, cyl4, cyl5, box4, box5]))
fixedJaw = doc.addObject("Part::Feature", "FixedJaw")
fixedJaw.Shape = shape.removeSplitter()
fixedJaw.Placement.Rotation.Axis = App.Vector(0, 0, 1)
fixedJaw.Placement.Rotation.Angle = math.radians(180)

box1 = Part.makeBox(35, 40, 75, App.Vector(0, -20, -22))
cyl1 = Part.makeCylinder(35, 80, App.Vector(0, -40, 53), App.Vector(0, 1, 0), 90)
box2 = Part.makeBox(20, 80, 30, App.Vector(-20, -40, 58))
cyl2 = Part.makeCylinder(15, 80, App.Vector(-15, -40, 58), App.Vector(0, 1, 0), 90)
box3 = Part.makeBox(160, 24, 24, App.Vector(-160, -12, -12))
box4 = Part.makeBox(5, 80, 15, App.Vector(-20, -40, 58))
box5 = Part.makeBox(160, 18, 18, App.Vector(-160, -9, -9))
cyl3 = Part.makeCylinder(20, 55, App.Vector(-20, -40, 53), App.Vector(1, 0, 0))
cyl4 = Part.makeCylinder(20, 55, App.Vector(-20, 40, 53), App.Vector(1, 0, 0))
cyl5 = Part.makeCylinder(5, 35, App.Vector(0, 0, 38), App.Vector(1, 0, 0))
box6 = Part.makeBox(7, 88, 15, App.Vector(-22, -44, 75))
shape = box1.fuse([cyl1, box2, box3, box6]).cut(cyl2.fuse([box4, cyl3, cyl4, box5, cyl5]))
movableJaw = doc.addObject("Part::Feature", "MovableJaw")
movableJaw.Shape = shape.removeSplitter()
movableJaw.Placement.Base = App.Vector(150, 100, 0)

cyl1 = Part.makeCylinder(5, 190, App.Vector(0, 0, 0), App.Vector(1, 0, 0))
cyl2 = Part.makeCylinder(10, 20, App.Vector(190, 0, 0), App.Vector(1, 0, 0))
cyl3 = Part.makeCylinder(4, 100, App.Vector(200, 0, -50), App.Vector(0, 0, 1))
shape = cyl1.fuse([cyl2, cyl3])
leverScrew = doc.addObject("Part::Feature", "LeverScrew")
leverScrew.Shape = shape.removeSplitter()
leverScrew.Placement.Base = App.Vector(150, -100, 0)

wire1 = Part.makePolygon([App.Vector(0, 0, 100), App.Vector(0, 0, 0), App.Vector(100, 0, 0)])
crank = doc.addObject("Part::Feature", "Crank")
crank.Shape = wire1
crank.Placement.Base = App.Vector(0, -100, 0)

mat = fixedJaw.ViewObject.ShapeAppearance[0]
mat.DiffuseColor = (0.80, 0.60, 0.15, 0.0)
fixedJaw.ViewObject.ShapeAppearance = (mat,)

mat = movableJaw.ViewObject.ShapeAppearance[0]
mat.DiffuseColor = (0.55, 0.70, 0.70, 0.0)
movableJaw.ViewObject.ShapeAppearance = (mat,)

mat = leverScrew.ViewObject.ShapeAppearance[0]
mat.DiffuseColor = (0.70, 0.30, 0.20, 0.0)
leverScrew.ViewObject.ShapeAppearance = (mat,)

doc.recompute()
view = Gui.ActiveDocument.ActiveView
view.viewIsometric()
view.fitAll()

Dodawanie złożenia

Dodaj złożenie do dokumentu korzystając z narzędzia Utwórz złożenie.

Przenieś części do kontenera złożeń

W widoku drzewa przeciągnij i upuść części na obiekt Złożenia. Teraz mogą być one obsługiwane przez solver złożeń.

Kotwienie części

Aby utrzymać złożenie w żądanej pozycji, stała szczęka powinna być zablokowana (zakotwiona, jak się to określa w tym przypadku). Wybierz ją w widoku drzewa lub w widoku 3D i użyj narzędzia Włącz / wyłącz zakotwienie. Obiekt GroundedJoint zostanie dodany do kontenera połączeń.

Zastosuj połączenia

  • Połączenie obrotowe między stałą szczęką a korbą.

Zaznaczone elementy + Utwórz połączenie obrotowe → przestawiona korba.

  • Połączenie przesuwne między stałą a ruchomą szczęką

Selected elements + Utwórz połączenie przesuwne → przestawiona ruchoma szczęka

Ustaw minimalną długość na -77 mm i maksymalną długość na -7 mm. To ogranicza rozwarcie imadła do 70 mm.

Następne trzy połączenia są konieczne do zmuszenia śruby do: przesuwania jak ruchoma szczęka, obrotu jak korba i obrotu wokół głównej osi.

  • Połączenie dystansowe między śrubą a ruchomą szczęką

Zaznaczone elementy + Utwórz połączenie dystansowe → przestawiona śruba

Wybierz dwie ściany. Ustaw odległość na 20 mm.

  • Połączenie równoległe między śrubą a korbą

Zaznaczone elementy + Utwórz połączenie równoległe → przestawiona śruba

  • Połączenie cylindryczne między śrubą a stałą szczęką

Zaznaczone elementy + Utwórz połączenie cylindryczne → przestawiona śruba

  • Połączenie śrubowe między ruchomą szczęką a korbą

Zaznaczone elementy (śruba niewidoczna) + Utwórz połączenie śrubowe → cały mechanizm imadła (śruba widoczna)

Jeśli to konieczne, schowaj śrubę podczas wskazywania.

Ustaw promień skoku na 5 mm

Napęd imadła

Imadło może być napędzane poprzez poruszanie korbą i ruchomą szczęką przy pomocy lewego przycisku myszy.

Przykład - amortyzator

Ten przykład jest tymczasowy i może zostać usunięty gdy pojawią się odpowiednie opisy/przykłady.

Złożenie amortyzatora

W tym przykładzie tworzony jest amortyzator.

Złożenie składa się z trzech części bryłowych: tłoka, cylindra i sprężyny. Potrzebne są również trzy dodatkowe elementy niebryłowe - dwie osie i pręt. Wszystkie części są połączone kilkoma połączeniami.

Zawias tłoka obraca się wokół osi 2, podczas gdy zawias cylindra przesuwa się na łuku okręgu wyśrodkowanego na osi 1. Niebryłowy pręt jest wykorzystywany do tego ruchu. Długość pręta jest promieniem łuku.

Przygotowanie części

Poniższy kod Pythona utworzy nowy dokument z 6 obiektami. Utwórz nowe makro i wklej poniższy kod do edytora Pythona (nie do konsoli Pythona). Następnie uruchom to makro.

Poniższy kod nie może zostać uruchomiony z konsoli Pythona, ponieważ sprężyna musi być obiektem Part::FeaturePython definiowanym przez klasę z funkcjami zwrotnymi execute() i onChanged(). Tylko wtedy można zmienić jej wysokość poprzez właściwość.

import math
import FreeCAD as App
import FreeCADGui as Gui
import Part

doc = App.newDocument()

class Spring():
    def __init__(self, spring):
        spring.addProperty("App::PropertyLength", "Height", "Spring", "Height of the helix").Height = 200.0
        spring.Proxy = self
        spring.ViewObject.Proxy = 0
        
    def execute(self, spring):
        helix = Part.makeHelix(spring.Height/8.5, spring.Height, 35)
        startPnt = helix.Edges[0].Curve.value(0)
        section = Part.Wire([Part.Circle(startPnt, App.Vector(0, 1, 0), 5).toShape()])
        hel1 = helix.makePipeShell([section], True, True)
        box1 = Part.makeBox(80, 80, 10, App.Vector(-40, -40, -10))
        box2 = Part.makeBox(80, 80, 10, App.Vector(-40, -40, spring.Height))
        shape = hel1.cut(box1).cut(box2)
        spring.Shape = shape
        
    def onChanged(self, spring, prop):
        if prop == "Height":
            self.execute(spring) 
            
spring = doc.addObject("Part::FeaturePython", "Spring")
Spring(spring)
spring.Placement.Base = App.Vector(0, 100, 0)

axle1 = doc.addObject("Part::Line", "Axle1")
axle1.X2 = 0
axle1.Y2 = 80
axle1.Z2 = 0

axle2 = doc.addObject("Part::Line", "Axle2")
axle2.X2 = 0
axle2.Y2 = 80
axle2.Z2 = 0
axle2.Placement.Base = App.Vector(120, 0, -250)

rod = doc.addObject("Part::Line", "Rod")
rod.X2 = 100
rod.Y2 = 0
rod.Z2 = 0
rod.Placement.Base = App.Vector(0, -50, 0)

cyl1 = Part.makeCylinder(40, 10,App.Vector(0, 0, -5))
tor1 = Part.makeTorus(40, 5)
cyl2 = Part.makeCylinder(45, 5)
box1 = Part.makeBox(30, 10, 30,App.Vector(-15, -5, -35))
cyl3 = Part.makeCylinder(15, 10, App.Vector(0, -5, -35), App.Vector(0, 1, 0))
cyl4 = Part.makeCylinder(40, 5)
cyl5 = Part.makeCylinder(5, 10,App.Vector(0, -5, -35), App.Vector(0, 1, 0))
cyl6 = Part.makeCylinder(5, 130)
cyl7 = Part.makeCylinder(20, 5,App.Vector(0, 0, 130))
shape = cyl1.fuse([tor1,cyl2, box1, cyl3]).cut(cyl4.fuse([cyl5])).fuse([cyl6, cyl7])
piston = doc.addObject("Part::Feature", "Piston")
piston.Shape = shape.removeSplitter()
piston.Placement.Base = App.Vector(200, 100, -200)

cyl1 = Part.makeCylinder(40, 10,App.Vector(0, 0, -5))
tor1 = Part.makeTorus(40, 5)
cyl2 = Part.makeCylinder(45, 5)
box1 = Part.makeBox(30, 10, 30,App.Vector(-15, -5, -35))
cyl3 = Part.makeCylinder(15, 10,App.Vector(0, -5, -35), App.Vector(0, 1, 0))
cyl4 = Part.makeCylinder(40, 5)
cyl5 = Part.makeCylinder(5, 10,App.Vector(0, -5, -35), App.Vector(0, 1, 0))
cyl6 = Part.makeCylinder(25, 130)
tor2 = Part.makeTorus(20, 5,App.Vector(0, 0, 130))
cyl7 = Part.makeCylinder(20, 135)
cyl8 = Part.makeCylinder(20, 130)
cyl9 = Part.makeCylinder(5, 135)
shape = cyl1.fuse([tor1, cyl2, box1, cyl3]).cut(cyl4.fuse([cyl5])).fuse([cyl6, tor2, cyl7]).cut(cyl8.fuse([cyl9]))
cylinder = doc.addObject("Part::Feature", "Cylinder")
cylinder.Shape = shape.removeSplitter()
cylinder.Placement.Rotation.Axis = App.Vector(0, 1, 0)
cylinder.Placement.Rotation.Angle = math.pi
cylinder.Placement.Base = App.Vector(100, 100, 0)

mat = piston.ViewObject.ShapeAppearance[0]
mat.DiffuseColor = (0.80, 0.60, 0.15, 0.0)
piston.ViewObject.ShapeAppearance = (mat,)

mat = cylinder.ViewObject.ShapeAppearance[0]
mat.DiffuseColor = (0.55, 0.70, 0.70, 0.0)
cylinder.ViewObject.ShapeAppearance = (mat,)

doc.recompute()
view = Gui.ActiveDocument.ActiveView
view.viewIsometric()
view.fitAll()

Dodawanie złożenia

Dodaj złożenie do dokumentu korzystając z narzędzia Utwórz złożenie.

Przenieś części do kontenera złożeń

W Widoku drzewa przeciągnij i upuść części na obiekt Złożenia. Teraz mogą być one obsługiwane przez solver złożeń.

Zakotwienie dwóch osi

Aby utrzymać złożenie w żądanej pozycji, dwie osie powinny być zablokowane (zakotwione, jak się to określa w tym przypadku). Wybierz je w widoku drzewa lub w widoku 3D i użyj narzędzia Włącz / wyłącz zakotwienie. Dwa obiekty GroundedJoint zostaną dodane do kontenera połączeń.

Zastosuj połączenia

  • Połączenie obrotowe między osią 1 i tłokiem

Utwórz połączenie obrotowe + Wybrane elementy → przestawiony tłok

  • Połączenie przesuwne między tłokiem a cylindrem

Utwórz połączenie przesuwne + Wybrane elementy → przestawiony i przesunięty cylinder

Uważaj na lokalizację układu położenia przed wskazaniem ściany. Powinien on być na środku każdej ściany.

Przeciągnij cylinder aby utworzyć przerwę między nim i tłokiem. Ściany stanowiące podstawy dla sprężyny powinny być widoczne.

  • Połączenie dystansowe między tłokiem a cylindrem

Utwórz połączenie dystansowe + Wybrane ściany → przestawiony cylinder z odległością ustawioną na 200 mm

Ustaw wartość odległości na 200 mm.

Następne dwa połączenia są konieczne aby zmusić zawias cylindra do ruchu po łuku okręgu.

  • Połączenie cylindryczne między osią 1 a prętem

Utwórz połączenie cylindryczne + Wybrane elementy → przestawiony pręt

Upewnij się, że oś Z układu współrzędnych (niebieska) jest prostopadła do pręta wybierając punk końcowy.

  • Połączenie obrotowe między prętem a cylindrem

Utwórz połączenie obrotowe + Wybrane elementy → przestawiony cylinder

Ponownie upewnij się, że oś Z układu współrzędnych (niebieska) jest prostopadła do pręta.

Możesz napotkać problemy z tym połączeniem. Jeśli tak jest, spróbuj:

  1. Usunąć połączenie.
  2. Przełączyć się na widok z przodu.
  3. Obrócić złożenie (przeciągając tłok) i pręt, tak że środek otworu zawiasu cylindra leży na pręcie.
  4. Utworzyć połączenie ponownie.

Następne dwa połączenia są konieczne aby zamocować sprężynę do ściany podstawy.

  • Połączenie równoległe między sprężyną a tłokiem

Utwórz połączenie równoległe + Wybrane ściany → przestawiona sprężyna

Wybierz środek ściany podstawy tłoka i środek dolnej ściany sprężyny. Zachowaj wartość odległości 0.

  • Połączenie stałe między sprężyną a tłokiem

Utwórz połączenie stałe + Wybrane elementy → przestawiona sprężyna

Wybierz dolny wierzchołek szwu cylindra tłoka i narożnikowy wierzchołek sprężyny.

  • Połącz właściwość odległości połączenia Distance z właściwością Height sprężyny używając wyrażenia:
  1. Wybierz sprężynę w widoku drzewa.
  2. Wybierz niebiską ikonę w polu właściwości Height.
  3. Wprowadź w edytorze wyrażeń: <<Distance>>.Distance

Napęd amortyzatora

Aby ruszać amortyzatorem, kliknij dwukrotnie na obiekcie Distance w widoku drzewa i zmień jego właściwość Distance. Przelicz dokument. Sprężyna zmieni swoją długość.